package com.lft10.sync;

/**
 * Function: 		A {@code UnsafeBank} object 演示不安全的银行取款.<br/>
 * Reason:   		线程不安全.<br/>
 * Date:            2021-01-27 20:48<br/>
 * <p>
 * Class Name:      UnsafeBank<br/>
 * Package Name:    com.lft10.sync<br/>
 * @author Laifengting / E-mail:laifengting@foxmail.com
 * @version 1.0.0
 * @since JDK 8
 */
public class UnsafeBank {
	public static void main(String[] args) {
		// 账户
		Account account = new Account(100, "基金");
		Drawing you = new Drawing(account, 50, "你");
		Drawing girlFriend = new Drawing(account, 100, "女友");
		you.start();
		girlFriend.start();
	}
}

/**
 * 账户
 */
class Account {
	/**
	 * 账户中的余额
	 */
	int money;
	
	/**
	 * 卡名
	 */
	String name;
	
	public Account(int money, String name) {
		this.money = money;
		this.name = name;
	}
}

/**
 * 银行：模拟取款
 */
class Drawing extends Thread {
	/**
	 * 账户
	 */
	private Account account;
	/**
	 * 取钱数量
	 */
	private int drawingMoney;
	
	/**
	 * 现在手里有多少钱
	 */
	private int nowMoney;
	
	public Drawing(Account account, int drawingMoney, String name) {
		super(name);
		this.account = account;
		this.drawingMoney = drawingMoney;
	}
	
	/**
	 * synchronized 修饰方法时，默认锁的是this
	 */
	@Override
	public void run() {
		// 同步代码块中，锁的对象就是变化的量。需要增删改的对象。
		synchronized (account) {
			// 判断有没有钱
			if ((account.money - drawingMoney) < 0) {
				System.out.println(Thread.currentThread().getName() + "钱不够，取不了。");
				return;
			}
			
			// 模拟延时 放大问题的发生性
			try {
				Thread.sleep(10);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			
			// 账户内余额 = 余额 - 取出的钱
			account.money = account.money - drawingMoney;
			
			// 手里的钱
			nowMoney = nowMoney + drawingMoney;
			System.out.println(account.name + " 余额为： " + account.money);
			// this.getName() = Thread.currentThread().getName()
			System.out.println(this.getName() + " 手里的钱 " + nowMoney);
		}
	}
}


